package net.zdsoft.wpchat.support.action.advanced;

import java.io.IOException;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.annotation.Resource;

import org.apache.commons.codec.binary.Base64;

import net.zdsoft.keel.action.ActionContext;
import net.zdsoft.keel.util.DateUtils;
import net.zdsoft.keel.util.SecurityUtils;
import net.zdsoft.keel.util.ServletUtils;
import net.zdsoft.keel.util.StringUtils;
import net.zdsoft.keel.util.Validators;
import net.zdsoft.wpchat.android.client.BasicAction;
import net.zdsoft.wpchat.support.entity.ResultPack;
import net.zdsoft.wpchat.support.service.SqlTaskService;

/**
 * Sql任务执行模块
 * 
 * @author xuan
 * @version $Revision: 1.0 $, $Date: 2014-9-21 下午3:38:25 $
 */
public class SqlExecuteTaskAction extends BasicAction {
    private static final long serialVersionUID = 3283247191754137508L;

    private static final String SELECT = "select ";
    private String key;
    private String taskContent;
    private boolean isSelect = false;
    private ResultPack[] resultPacks;
    private int[] resultCodes;
    private int resultIndex;

    private String[] wildcards;
    private String[] wildcardValues;
    private static String COOKIE_KEY_SQL = "AdvancedTaskAction.sqlContent";
    @Resource
    private SqlTaskService sqlTaskService;

    /**
     * 获取Sql执行任务
     * 
     * @return
     */
    public String getSqlTask() {
        String sqlContent = ServletUtils.getCookie(ActionContext.getRequest(), COOKIE_KEY_SQL);
        if (!Validators.isEmpty(sqlContent)) {
            try {
                taskContent = new String(Base64.decodeBase64(sqlContent));
                taskContent = URLDecoder.decode(taskContent, "UTF-8");
            }
            catch (Exception e) {
                logger.error(e.getMessage(), e);
            }

        }
        return SUCCESS;
    }

    /**
     * 执行Sql
     * 
     * @return
     * @throws Exception
     */
    public String sqlExecute() throws Exception {
        if (Validators.isEmpty(taskContent)) {
            addActionError("请输入您要执行的任务");
            return SUCCESS;
        }
        String encodeSQL = taskContent;
        taskContent = new String(Base64.decodeBase64(taskContent.getBytes())).trim();
        taskContent = URLDecoder.decode(taskContent, "UTF-8");
        String sqlContent = taskContent;
        ServletUtils.addCookie(ActionContext.getResponse(), COOKIE_KEY_SQL, encodeSQL, 30 * 24 * 3600);
        if (wildcards != null) {
            Pattern pattern = Pattern.compile("\\$\\{.+?\\}");
            Matcher matcher = pattern.matcher(sqlContent);
            Map<String, String> wildcard2ValueMap = new HashMap<String, String>();
            for (int i = 0; i < wildcards.length; i++) {
                wildcard2ValueMap.put(wildcards[i], wildcardValues[i]);
            }

            for (; matcher.find();) {
                sqlContent = StringUtils.replace(sqlContent, matcher.group(), wildcard2ValueMap.get(matcher.group()));
            }
        }

        String[] sqls = new String[0];
        try {
            sqls = sqlTaskService.splitSql(sqlContent, true);
        }
        catch (IOException e) {
            addActionError("SQL 语句解析异常");
            return SUCCESS;
        }
        isSelect = true;
        for (String sql : sqls) {
            if (!Validators.isEmpty(sql) && !sql.trim().toLowerCase().startsWith(SELECT)) {
                isSelect = false;
                break;
            }
        }
        if (isSelect) {
            try {
                resultPacks = sqlTaskService.executeQuery(sqlContent, resultIndex);
            }
            catch (Exception e) {
                logger.warn(e.getMessage(), e);
                addActionError(StringUtils.htmlFilter(e.toString()));
                return SUCCESS;
            }
        }
        else {
            // 更新数据需要验证口令
            if (Validators.isEmpty(key)) {
                addActionError("请输入权限验证的口令");
                return SUCCESS;
            }

            String correctKey = SecurityUtils.encodeBySHA1(DateUtils.currentDate2StringByDay()
                    + "308959644daa7c8b6aad56150d83a008b70231a6");
            logger.debug("correctKey:" + correctKey);
            if (!correctKey.equals(key)) {
                addActionError("口令错误");
                return SUCCESS;
            }

            isSelect = false;
            try {
                resultCodes = sqlTaskService.executeUpdate(sqlContent);
            }
            catch (Exception e) {
                logger.warn(e.getMessage(), e);
                addActionError(StringUtils.htmlFilter(e.toString()));
                return SUCCESS;
            }
        }
        return SUCCESS;
    }

    public static void main(String[] args) {
        String correctKey = SecurityUtils.encodeBySHA1(DateUtils.currentDate2StringByDay()
                + "308959644daa7c8b6aad56150d83a008b70231a6");
        System.out.println(correctKey);
    }

    public String getKey() {
        return key;
    }

    public String getTaskContent() {
        return taskContent;
    }

    public void setKey(String key) {
        this.key = key;
    }

    public void setTaskContent(String taskContent) {
        this.taskContent = taskContent;
    }

    public boolean isSelect() {
        return isSelect;
    }

    public ResultPack[] getResultPacks() {
        return resultPacks;
    }

    public int getResultIndex() {
        return resultIndex;
    }

    public void setResultPacks(ResultPack[] resultPacks) {
        this.resultPacks = resultPacks;
    }

    public void setResultIndex(int resultIndex) {
        this.resultIndex = resultIndex;
    }

    public ResultPack getCurrentResultPack() {
        if (resultPacks.length - 1 < resultIndex) {
            return null;
        }
        return resultPacks[resultIndex];
    }

    public int[] getResultCodes() {
        return resultCodes;
    }

    public void setResultCodes(int[] resultCodes) {
        this.resultCodes = resultCodes;
    }

    public String[] getWildcards() {
        return wildcards;
    }

    public String[] getWildcardValues() {
        return wildcardValues;
    }

    public void setWildcards(String[] wildcards) {
        this.wildcards = wildcards;
    }

    public void setWildcardValues(String[] wildcardValues) {
        this.wildcardValues = wildcardValues;
    }

    public void setSelect(boolean isSelect) {
        this.isSelect = isSelect;
    }

}
